/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.nc.kyiv.yellow.sociallibrary.reporting.render;

import com.nc.kyiv.yellow.sociallibrary.reporting.data.ReportNode;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.WorkbookUtil;

/**
 *
 * @author NightmaresSeller
 */
public class BIReportXLSRenderer implements IReportRenderer {
    
    private String outputFileName;
    
    protected ReportNode root;
    protected HSSFWorkbook reportWb;
    protected int gridStartRow;
    
    public BIReportXLSRenderer(String outputFileName) {
        this.outputFileName = outputFileName;
    }
    
    public void render(ReportNode reportRoot) throws ReportRenderingException {
        this.root = reportRoot;
        String str = "Foo";
        switch (str) {
            case "Foo":{str = "Bar"; break;}
            case "Bar":{str = "Foo"; break;}
        }
        
        reportWb = new HSSFWorkbook();
        // Converting name of root node, used as sheet name, to form safe for all xls viewers 
        root.setName(WorkbookUtil.createSafeSheetName(root.getName()));
        Sheet reportSheet = reportWb.createSheet(root.getName());
        
        List nodes;
        nodes = root.getChildByName("PageHeader");
        if (!nodes.isEmpty()) {
            renderPageHeader((ReportNode) nodes.get(0));
        }
        nodes = root.getChildByName("Title");
        if (!nodes.isEmpty()) {
            renderTitle((ReportNode) nodes.get(0));
        }
        nodes = root.getChildByName("BIGrid");
        if (!nodes.isEmpty()) {
            renderBIGrid((ReportNode) nodes.get(0));
        }
        nodes = root.getChildByName("PageFooter");
        if (!nodes.isEmpty()) {
            renderPageFooter((ReportNode) nodes.get(0));
        }
        try {
            writeReportWorkbook();
        } catch (IOException ex) {
            throw new ReportRenderingException("Error when writing report to file \"" 
                    + outputFileName + "\"", 
                    ex);
        }
    }
    
    protected void renderBIGrid(ReportNode grid) {
        List nodes;
        nodes = grid.getChildByName("BIGridRow");
        if (!nodes.isEmpty()) {
            for (int i = 0; i < nodes.size(); i++) {
                renderBIGridRow((ReportNode) nodes.get(i), i);
            }
        }
    }
    
    protected void renderBIGridRow(ReportNode row, int index) {
        Sheet reportSheet = reportWb.getSheet(root.getName());
        Row biRow = reportSheet.createRow(gridStartRow + index);
        
        Cell infoCells[] = new Cell[8];
        for (int i = 0; i < infoCells.length; i++) {
            infoCells[i] = biRow.createCell(i);
        }
        
        Object attribute;
        attribute = row.getAttribute("isbn");
        if (attribute != null) {
            infoCells[0].setCellValue(attribute.toString());
        }
        attribute = row.getAttribute("title");
        if (attribute != null) {
            infoCells[1].setCellValue(attribute.toString());
        }
        attribute = row.getAttribute("author");
        if (attribute != null) {
            infoCells[2].setCellValue(attribute.toString());
        }
        attribute = row.getAttribute("genre");
        if (attribute != null) {
            infoCells[3].setCellValue(attribute.toString());
        }
        attribute = row.getAttribute("pages");
        if (attribute != null) {
            infoCells[4].setCellValue(attribute.toString());
        }
        attribute = row.getAttribute("rating");
        if (attribute != null) {
            infoCells[5].setCellValue(attribute.toString());
        }
        attribute = row.getAttribute("pubdate");
        if (attribute instanceof Date) {
            infoCells[6].setCellValue((new SimpleDateFormat("yyyy-MM-dd")).format((Date) attribute));
        }
        attribute = row.getAttribute("publisher");
        if (attribute != null) {
            infoCells[7].setCellValue(attribute.toString());
        }
    }
    
    protected void renderTitle(ReportNode title) {
        Sheet reportSheet = reportWb.getSheet(root.getName());
        Row titleRow = reportSheet.createRow(3);
        
        Font titleFont = reportWb.createFont();
        titleFont.setFontName("Calibri");
        titleFont.setFontHeightInPoints((short) 20);
        
        CellStyle titleCellStyle = reportWb.createCellStyle();
        titleCellStyle.setFont(titleFont);
        titleCellStyle.setAlignment(CellStyle.ALIGN_CENTER);
        
        Cell titleCell = titleRow.createCell(0);
        titleCell.setCellStyle(titleCellStyle);
        
        Object attribute;
        attribute = title.getAttribute("text");
        if (attribute != null) {
            titleCell.setCellValue(attribute.toString());
        }
       
        reportSheet.addMergedRegion(new CellRangeAddress(3, 3, 0, 8));
        gridStartRow = 6;
    }
    
    protected void renderPageHeader(ReportNode pageHeader) {
        Header pageHead = reportWb.getSheet(root.getName()).getHeader();
        String headerText = "";
        Object attribute;
        attribute = pageHeader.getAttribute("datetime");
        if (attribute instanceof Date) {
            headerText = "Report generated " + (new SimpleDateFormat("yyyy-MM-dd HH:mm")).format((Date) attribute);
        }
        attribute = pageHeader.getAttribute("generationtime");
        if (attribute instanceof Integer) {
            headerText += " " + ((Integer) attribute).toString() + " ms"; 
        }
        pageHead.setLeft(headerText);
    }
    
    protected void renderPageFooter(ReportNode pageFooter) {
        // No footer need in this document
    }
    
    protected void writeReportWorkbook() throws FileNotFoundException, IOException {
        FileOutputStream fileOut = new FileOutputStream(outputFileName);
        reportWb.write(fileOut);
        fileOut.close();
    }
    
}
